package com.resou.reader;

import android.app.ActivityManager;
import android.app.Application;
import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.support.multidex.MultiDex;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.alibaba.sdk.android.feedback.impl.FeedbackAPI;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.request.RequestOptions;
import com.fm.openinstall.OpenInstall;
import com.google.gson.Gson;
import com.resou.reader.advert.TTAdManagerHolder;
import com.resou.reader.commom.Constant;
import com.resou.reader.crash.CrashHandler;
import com.resou.reader.utils.log.DLog;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.MsgConstant;
import com.umeng.message.PushAgent;
import com.umeng.message.UTrack;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;
import com.umeng.socialize.PlatformConfig;
import com.umeng.socialize.UMShareAPI;
import com.umeng.socialize.UMShareConfig;

import org.litepal.LitePalApplication;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.api.TagAliasCallback;
import me.jessyan.autosize.AutoSizeConfig;
import me.jessyan.autosize.unit.Subunits;

//import com.squareup.leakcanary.LeakCanary;

public class ReSouApplication extends LitePalApplication {

    private static final String TAG = "ReSouApplication";
    public static final String UPDATE_STATUS_ACTION = "com.umeng.message.example.action.UPDATE_STATUS";

    private Handler handler;
    public static int SCREEN_WIDTH = -1;
    public static int SCREEN_HEIGHT = -1;
    public static float DIMEN_RATE = -1.0F;
    public static int DIMEN_DPI = -1;
    public static Gson gson = new Gson();

    static {
        //未配置
        PlatformConfig.setWeixin("wx0e7e17a030a61e08", "11a4d3b869e31be7a1fe95d327d6565c");
        //未配置
        PlatformConfig.setSinaWeibo("2589012742", "75402e89554190b05ed12162a1e791e8", "http://sns.whalecloud.com");
        PlatformConfig.setQQZone("1107468224", "1hkTkKoPXCgOxp7C");
//        PlatformConfig.setQQZone("101501046", "8168c46df6c4120d341ba698f97574d8");
    }

    private static Application sApplication;

    @Override
    public void onCreate() {
        super.onCreate();
        sApplication = this;
//        if (LeakCanary.isInAnalyzerProcess(this)) {
//            // 此过程专用于LeakCanary进行堆分析。
//            // 您不应该在此过程中初始化您的应用。
//            return;
//        }
//        LeakCanary.install(this);
        TTAdManagerHolder.getInstance(this);
        JPushInterface.setDebugMode(true);
        JPushInterface.init(this);
        JPushInterface.setAlias(this, "测试2", new TagAliasCallback() {
            @Override
            public void gotResult(int i, String s, Set<String> set) {
                Log.i(TAG, "gotResult: 设置成功");
            }
        });
//        initAliFeedback();
//        initGlide();
//        //初始化屏幕宽高
//        getScreenSize();
////        initUMSDK();
////        initUMPUSH();
//        AutoSizeConfig.getInstance().getUnitsManager()
//                .setSupportDP(true)
//                .setSupportSP(true)
//                .setSupportSubunits(Subunits.MM);
        if (isMainProcess()) {
            initAliFeedback();
            initGlide();
            //初始化屏幕宽高
            getScreenSize();
            AutoSizeConfig.getInstance().getUnitsManager()
                    .setSupportDP(true)
                    .setSupportSP(true)
                    .setSupportSubunits(Subunits.MM);
            initUMSDK();
            initUMPUSH();
            OpenInstall.init(this);
        }
        //解决友盟平台错误统计org.litepal.exceptions.LitePalSupportException: unable to open database file (code 14)错误
        //https://ask.csdn.net/questions/334590
//        Connector.getDatabase().execSQL("PRAGMA temp_store_directory = '/data/data/com.resou.reader/databases'");
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        //通过反射解决部分oppo vivo xiaomi  hongmi等手机出现此问题finalize() timed out
        //https://www.jianshu.com/p/89e2719be9c7
        //https://www.jianshu.com/p/0119c682d2b8
        if (android.os.Build.MODEL.contains("oppo") ||
                android.os.Build.MODEL.contains("vivo") ||
                android.os.Build.MODEL.contains("红米") ||
                android.os.Build.MODEL.contains("小米") ||
                android.os.Build.MODEL.contains("OPPO") ||
                android.os.Build.MODEL.contains("VIVO") ||
                android.os.Build.MODEL.contains("hongmi") ||
                android.os.Build.MODEL.contains("xiaomi")) {
            fix();
        }
    }

    public static void fix() {
        try {
            Class clazz = Class.forName("java.lang.Daemons$FinalizerWatchdogDaemon");

            Method method = clazz.getSuperclass().getDeclaredMethod("stop");
            method.setAccessible(true);

            Field field = clazz.getDeclaredField("INSTANCE");
            field.setAccessible(true);

            method.invoke(field.get(null));

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public void getScreenSize() {
        WindowManager windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        assert windowManager != null;
        Display display = windowManager.getDefaultDisplay();
        display.getMetrics(dm);
        DIMEN_RATE = dm.density / 1.0F;
        DIMEN_DPI = dm.densityDpi;
        SCREEN_WIDTH = dm.widthPixels;
        SCREEN_HEIGHT = dm.heightPixels;
        if (SCREEN_WIDTH > SCREEN_HEIGHT) {
            int t = SCREEN_HEIGHT;
            SCREEN_HEIGHT = SCREEN_WIDTH;
            SCREEN_WIDTH = t;
        }
    }

    /**
     * 初始化阿里云 用户反馈
     */
    private void initAliFeedback() {
        FeedbackAPI.init(this, "25181212", "f98c3158fe302a0237825479c2febe1b");
//        FeedbackAPI.setHistoryTextSize(getResources().getDimension(R.dimen.qb_px_20));
        FeedbackAPI.setBackIcon(R.drawable.ic_back);
        FeedbackAPI.setTranslucent(false);//不适用沉侵式任务栏
//        FeedbackAPI.setDefaultUserContactInfo("025-83323208");//设置用户的联系方式
    }

    /**
     * 初始化Umeng Push SDK
     */
    private void initUMPUSH() {
        final PushAgent mPushAgent = PushAgent.getInstance(this);

        mPushAgent.onAppStart();//友盟统计app启动次数，如不开启可能会因为，尝长时间不登录而推送失败
        handler = new Handler(getMainLooper());

        //sdk开启通知声音
        mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE);
        // sdk关闭通知声音
        // mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);
        // 通知声音由服务端控制
        // mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SERVER);

        // mPushAgent.setNotificationPlayLights(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);
        // mPushAgent.setNotificationPlayVibrate(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);

        UmengMessageHandler messageHandler = new UmengMessageHandler() {

            /**
             * 通知的回调方法（通知送达时会回调）
             */
            @Override
            public void dealWithNotificationMessage(Context context, UMessage msg) {
                //调用super，会展示通知，不调用super，则不展示通知。
                super.dealWithNotificationMessage(context, msg);
                Map<String, String> map = msg.extra;
                for (Map.Entry<String, String> entity : map.entrySet()) {
                    String key = entity.getKey();
                    String value = entity.getValue();
                    DLog.d(TAG, "key:" + key + " ,value:" + value);
                }
            }

            /**
             * 自定义消息的回调方法
             */
            @Override
            public void dealWithCustomMessage(final Context context, final UMessage msg) {

                handler.post(() -> {
                    // 对自定义消息的处理方式，点击或者忽略
                    boolean isClickOrDismissed = true;
                    if (isClickOrDismissed) {
                        //自定义消息的点击统计
                        UTrack.getInstance(getApplicationContext()).trackMsgClick(msg);
                    } else {
                        //自定义消息的忽略统计
                        UTrack.getInstance(getApplicationContext()).trackMsgDismissed(msg);
                    }
                    Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
                });
            }

            /**
             * 自定义通知栏样式的回调方法
             */
            @Override
            public Notification getNotification(Context context, UMessage msg) {
                switch (msg.builder_id) {
                    case 1:
                        Notification.Builder builder = new Notification.Builder(context);
                        RemoteViews myNotificationView = new RemoteViews(context.getPackageName(),
                                R.layout.notification_view);
                        myNotificationView.setTextViewText(R.id.notification_title, msg.title);
                        myNotificationView.setTextViewText(R.id.notification_text, msg.text);
                        myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));
                        myNotificationView.setImageViewResource(R.id.notification_small_icon,
                                getSmallIconId(context, msg));
                        builder.setContent(myNotificationView)
                                .setSmallIcon(getSmallIconId(context, msg))
                                .setTicker(msg.ticker)
                                .setAutoCancel(true);
                        return builder.getNotification();
                    default:
                        //默认为0，若填写的builder_id并不存在，也使用默认。
                        return super.getNotification(context, msg);
                }
            }
        };


        mPushAgent.setMessageHandler(messageHandler);

        /**
         * 自定义行为的回调处理，参考文档：高级功能-通知的展示及提醒-自定义通知打开动作
         * UmengNotificationClickHandler是在BroadcastReceiver中被调用，故
         * 如果需启动Activity，需添加Intent.FLAG_ACTIVITY_NEW_TASK
         *
         */
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {

            @Override
            public void launchApp(Context context, UMessage msg) {
                super.launchApp(context, msg);
            }

            @Override
            public void openUrl(Context context, UMessage msg) {
                super.openUrl(context, msg);
//                msg.
                Log.i(TAG, "openUrl: " + msg.text);
            }

            @Override
            public void openActivity(Context context, UMessage msg) {
                super.openActivity(context, msg);
                Log.i(TAG, "openActivity: " + msg.text);

            }

            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
            }
        };
        //使用自定义的NotificationHandler
        mPushAgent.setNotificationClickHandler(notificationClickHandler);

        //注册推送服务 每次调用register都会回调该接口
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                Log.i(TAG, "device token: " + deviceToken);
                sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }

            @Override
            public void onFailure(String s, String s1) {
                Log.i(TAG, "register failed: " + s + " " + s1);
                sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }
        });

        //使用完全自定义处理
        //mPushAgent.setPushIntentServiceClass(UmengNotificationService.class);
//        HuaWeiRegister.register(this);
        //小米通道
        //MiPushRegistar.register(this,
    }

    private void initGlide() {
        Glide.with(this).setDefaultRequestOptions(new RequestOptions().format(DecodeFormat.PREFER_RGB_565).placeholder(R.mipmap.ic_place).error(R.mipmap.ic_place));
    }

    private void initUMSDK() {
        UMShareAPI api = UMShareAPI.get(this);
        UMShareConfig config = new UMShareConfig();
        config.isNeedAuthOnGetUserInfo(true);
        api.setShareConfig(config);
        MobclickAgent.openActivityDurationTrack(false);
        UMConfigure.setLogEnabled(false);//打开友盟sdk日志
        UMConfigure.setEncryptEnabled(false);//日志加密
        boolean debugLog = UMConfigure.isDebugLog();

        /**
         * 参数1:上下文，必须的参数，不能为空。
         * 参数2:【友盟+】 AppKey，非必须参数，如果Manifest文件中已配置AppKey，该参数可以传空，则使用Manifest中配置的AppKey，否则该参数必须传入。
         * 参数3:【友盟+】 Channel，非必须参数，如果Manifest文件中已配置Channel，该参数可以传空，则使用Manifest中配置的Channel，否则该参数必须传入，Channel命名请详见Channel渠道命名规范。
         * 参数4:设备类型，必须参数，传参数为UMConfigure.DEVICE_TYPE_PHONE则表示手机；传参数为UMConfigure.DEVICE_TYPE_BOX则表示盒子；默认为手机。
         * 参数5:Push推送业务的secret，需要集成Push功能时必须传入Push的secret，否则传空。
         */
//        UMConfigure.init(this, Constant.UM_APPKEY, Constant.UMENG_CHANNEL, UMConfigure.DEVICE_TYPE_PHONE, Constant.UM_MESSAGE_SECRET);
        UMConfigure.init(this, Constant.UM_APPKEY, getChannel(), UMConfigure.DEVICE_TYPE_PHONE, Constant.UM_MESSAGE_SECRET);
        //统计场景
        MobclickAgent.setScenarioType(this, MobclickAgent.EScenarioType.E_UM_NORMAL);
        //防止AppKey被盗
        MobclickAgent.setSecret(this, Constant.UM_MASTER_SECRET);

        // latitude: 纬度
        // longitude: 经度
//        MobclickAgent.setLocation(double latitude, double longitude);

        //捕获异常
//        MobclickAgent.setCatchUncaughtExceptions(false);
        /**
         * 全局异常捕获，发布时 关闭
         */
        CrashHandler.getInstance().init(this);
        UMConfigure.setLogEnabled(true);
    }

    public static Application getRSApplication() {
        return sApplication;
    }

    private String getChannel() {
        try {
            PackageManager pm = getPackageManager();
            ApplicationInfo appInfo = pm.getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            return appInfo.metaData.getString("UMENG_CHANNEL");
        } catch (PackageManager.NameNotFoundException ignored) {
        }
        return "";
    }

    /**
     * 是否在主线线程
     *
     * @return
     */
    public boolean isMainProcess() {
        int pid = android.os.Process.myPid();
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager.getRunningAppProcesses() != null) {
            for (ActivityManager.RunningAppProcessInfo appProcess : activityManager.getRunningAppProcesses()) {
                if (appProcess.pid == pid) {
                    return getApplicationInfo().packageName.equals(appProcess.processName);
                }
            }
        }
        return false;
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Glide.get(this).clearMemory();
        System.gc();
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_UI_HIDDEN) {
            Glide.get(this).clearMemory();
        }
        Glide.get(this).trimMemory(level);
    }
}
